package com.vimi8.ebb.auth.manage;

import com.vimi8.ebb.auth.configuration.HttpResponseEntity;
import com.vimi8.ebb.auth.configuration.OAuth2AuthenticationImpl;
import com.vimi8.ebb.auth.dto.AuthUserDto;
import com.vimi8.ebb.auth.model.*;
import com.vimi8.ebb.auth.model.Error;
import com.vimi8.ebb.auth.utils.CommonUtil;
import com.vimi8.ebb.auth.utils.MessageUtil;
import com.vimi8.ebb.auth.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * Created by think on 2016/12/2.
 */
@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class OrgManageImpl implements OrgManage {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    UserAuthorityService userAuthorityService;
    @Autowired
    private DBClientDetailsService dbClientDetailsService;
    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private GeoCodingsService geoCodingsService;
    @Autowired
    private MyMessageService myMessageService;

    @Override
    public Integer approval(String orgId, String userId,int isApproval) throws Exception {

        //1.先获取申请记录
        //2.向organization_emp添加组织员工信息
        //3.向oauth_client_user插入权限信息

       Organization organizationCorp= organizationService.getOrganization(orgId);
        //如果没有userId则默认取组织法人userId
        if(StringUtils.isEmpty(userId)){
            userId=organizationCorp.getOrgCorp();
        }

        UserApplyClientResource userApplyClientResource= userAuthorityService.queryUserApplyClient(userId,orgId);
        logger.info("userApplyClientResource="+userApplyClientResource);
        int count=0;
        DBClientDetails clientDetails = null;
        OrganizationDept organizationDept = new OrganizationDept();

        //判断审批状态 如果没有审批被拒绝 则不需要更新审批状态  因为默认的是 未通过
        if(0==isApproval){
            return count;
        }


        clientDetails = dbClientDetailsService.getClientDetailsByClientId(orgId);
        logger.info("clientDetails="+clientDetails);
        //根据clientId给用户配置自动资源
        LinkedHashSet<String> resourcesSet = new LinkedHashSet();
        //String resources = "default_resources";
        if (!StringUtils.isEmpty(clientDetails.getManuResources())) {
            resourcesSet.addAll(Arrays.asList(clientDetails.getManuResources().split("\\|")));
            //resources = clientDetails.getAutoResources();
        }
        //参考 部门,添加部门资源
        if (!StringUtils.isEmpty(organizationDept.getDeptResources())) {
            resourcesSet.addAll(Arrays.asList(organizationDept.getDeptResources().split("\\|")));
            //resources = clientDetails.getAutoResources();
        }
        if (resourcesSet.size() == 0) {
            resourcesSet.add("default_resources");
        }

        //根据clientId给用户配置自动权限
        LinkedHashSet<String> scopesSet = new LinkedHashSet();
        //String scopes = "default_scopes";
        if (!StringUtils.isEmpty(clientDetails.getManuScopes())) {
            scopesSet.addAll(Arrays.asList(clientDetails.getManuScopes().split("\\|")));
            //scopes = clientDetails.getAutoScopes();
        }
        //参考 部门,添加部门权限
        if (!StringUtils.isEmpty(organizationDept.getDeptScopes())) {
            scopesSet.addAll(Arrays.asList(organizationDept.getDeptScopes().split("\\|")));
            //resources = clientDetails.getAutoResources();
        }
        if (scopesSet.size() == 0) {
            scopesSet.add("default_scopes");
        }
        organizationDept = userAuthorityService.getOrganizationDept(orgId, "0");
        //查询applyOpenid是否存在,不存在则可使用该applyOpenid
        String openid = UUID.randomUUID().toString();

        String approvalOpenId= userAuthorityService.queryOpenidByUserIdAndClientId(userId,orgId);
        //如果根据user_id查询出有个人组织下的openId,则更新个人所在新组织下的权限
        //否则 插入新openId和新组织下的权限信息
        if(!StringUtils.isEmpty(approvalOpenId)){
            openid=approvalOpenId;
           userAuthorityService.updateOpenid(orgId, userId, openid, String.join("|", resourcesSet), String.join("|", scopesSet));
        }else{
            //用户插入组织(client域)
            //数据库，需保证resources,scopes  NOT NULL（已加约束），所以此处resources,scopes不能为null
            //logger.warn("clientId:"+clientId+",UserId:"+regUser.getUserId()+",openid:"+openid+",resources:"+resources+",scopes:"+scopes);
          //  userAuthorityService.getAuthUserDtoByOpenid()
        try {
            count += userAuthorityService.insertOpenid(orgId, userId, openid, String.join("|", resourcesSet), String.join("|", scopesSet));
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
       }

        //插入员工信息  员工必须有job字段标识  否则无权限
        OrganizationEmp organizationEmp = new OrganizationEmp();
        organizationEmp.setClientId(orgId);
        organizationEmp.setDeptId(organizationDept.getDeptId());
        organizationEmp.setUserId(userId);
        organizationEmp.setJob(userApplyClientResource.getJob());
        count += userAuthorityService.insertOrganizationEmp(organizationEmp);
        //审批通过之后 更新审批状态
        count+=  organizationService.updateApplyClientResource(userId,orgId,userApplyClientResource.getJob(),isApproval);
        String currentUserId= userAuthorityService.getCorpUserIdByClientId(orgId);
        Organization organization=   organizationService.getOrganization(orgId);
        String orgName=organization==null?"":organization.getOrgName();
        if("org_corp".equals(userApplyClientResource.getJob())){
            count+= organizationService.updateOrganizationApproval(orgId,isApproval);
            // 发送消息
            MessageQuery messageQuery=new MessageQuery();
            Map<String,Object> messageMap=new HashMap<>();
            messageMap.put("receiveId",currentUserId);
            messageMap.put("messClass","create_success");
            logger.info("messageMap="+messageMap);
            logger.info("organization"+organization);

            logger.info("orgName="+orgName);
            messageMap.put("FF",orgName);
            messageQuery.setMessMap(messageMap);
            MyMessage myMessage=    MessageUtil.dealMessageTags(userId,messageQuery,myMessageService);
            count+= myMessageService.insertMyMessage(myMessage);
        }else  if("org_emp".equals(userApplyClientResource.getJob())){
            count+= organizationService.updateOrganizationApproval(orgId,isApproval);
            // 发送消息
            MessageQuery messageQuery=new MessageQuery();
            Map<String,Object> messageMap=new HashMap<>();
            messageMap.put("receiveId",currentUserId);
            messageMap.put("messClass","join_farm");
            AuthUser authUser=userAuthorityService.getAuthUserByUserId(userId);
            String loginName=authUser==null?"":(StringUtils.isEmpty(authUser.getRealName())?(authUser.getPhoneNumber()):authUser.getRealName());
            messageMap.put("XX",loginName);
            messageMap.put("FF",orgName);
            messageQuery.setMessMap(messageMap);
            MyMessage myMessage=    MessageUtil.dealMessageTags(userId,messageQuery,myMessageService);
            count+= myMessageService.insertMyMessage(myMessage);
        }
        //更新oauth-user的默认客服端id
        userAuthorityService.updatDefaultClientId(orgId,openid);

        return count;
    }

    @Override
    public ClientDetails switchOrg(String newOrgId, String oldOrgId, String openId) throws Exception {

        ClientDetails clientDetails = null;
        try {
            clientDetails = dbClientDetailsService.getClientDetailsByClientId(newOrgId);
            if(clientDetails==null){
                throw new Exception("invalid client id");
            }
        } catch (Exception ex) {
            throw new Exception("invalid_param");
        }
        //更新默认客服端id
        try {
            userAuthorityService.updatDefaultClientId(newOrgId,openId);
        } catch (Exception e) {
            throw new Exception("update default_client_id error");
        }
        return clientDetails;
    }

    @Override
    public RegUser registerCorp(RegUser regUser, String autoRecource, String autoScopes) throws Exception {
        /**1.注册组织*/
        //不信任客户端传递的uid
        logger.info("regUser="+regUser);
        Integer count=0;
        regUser.setUserId(UUID.randomUUID().toString());
        HttpResponseEntity<RegUser> responseEntity = new HttpResponseEntity<RegUser>(HttpStatus.OK);
        Error error = null;
        if (regUser == null) {
            logger.info("organization is null");
            throw new Exception("organization is null");
        }
        //组织类型必须传
        if (regUser != null && StringUtils.isEmpty(regUser.getClientOrgClass())) {
            logger.info("org_type is require");
            throw new Exception("org_type is require");
        }

        int isCreatUser = 0; //如果是vimi8_com运营部门组织 则创建组织时,需要额外创建法人
   //     if(!"vimi8_com".equals(OAuth2AuthenticationImpl.clientId())){
//            isCreatUser = 1;
//            //如果不是vimi8_com运营部门组织 则创建新法人时,以传入的为准
//            AuthUserDto authUserDto = userAuthorityService.getAuthUserDtoByOpenid(OAuth2AuthenticationImpl.openId(), OAuth2AuthenticationImpl.clientId());
//            logger.info("authUserDto="+authUserDto);
//            regUser.setUserId(authUserDto.getUserId());
//            regUser.setUserName(authUserDto.getUserName());
//            regUser.setPhoneNumber(authUserDto.getPhoneNumber());

     //   } else {
//            if (StringUtils.isEmpty(regUser.getUserName())) {
//                logger.info("userName is empty ");
//                throw new Exception("userName is empty ");
//            } else
        String userId=  userAuthorityService.getUserId(regUser.getPhoneNumber());
        if(!StringUtils.isEmpty(userId)){
            isCreatUser=1;
            regUser.setUserId(userId);
        }
        if (!StringUtils.isEmpty(regUser.getPhoneNumber())&&!StringUtils.isEmpty(regUser.getPhoneNumber().trim()) && !CommonUtil.isMobileNO(regUser.getPhoneNumber())&&!CommonUtil.isLandlineNO(regUser.getPhoneNumber())&&!CommonUtil.is400NO(regUser.getPhoneNumber())) {
                logger.info("phoneNumber validate failed.");
                throw new Exception("手机号： "+regUser.getPhoneNumber()+" 格式不正确或者重复，验证失败. ");

            }
      //  }
        //组织模板信息
        OrganizationClass organizationClass = organizationService.getOrganizationClassByOrgClass(regUser.getClientOrgClass());
        //构造一个组织对象
        Organization organization = new Organization();
        if(StringUtils.isEmpty(regUser.getDefaultClientId())){
            organization.setClientId(UUID.randomUUID().toString());//ClientId
        }else{
            organization.setClientId(regUser.getDefaultClientId());//ClientId
        }

        organization.setAddressCode(regUser.getAddressCode());
        organization.setAddressDetail(regUser.getAddressDetail());
        organization.setRemark(regUser.getRemark());
        organization.setOrgImages(regUser.getOrgImages().toString());
        organization.setOrgClass(regUser.getClientOrgClass());
        organization.setAllowUsersToJoin(organizationClass.getAllowUsersToJoin());
        organization.setOrgName(regUser.getOrgName());
        organization.setOrgCorp(regUser.getUserId());//法人userId
        organization.setOrgClassDescription(organizationClass.getOrgClassDescription());
        organization.setAutoApproveResources(organizationClass.getAutoApproveResources());
        organization.setAutoApproveScopes(organizationClass.getAutoApproveScopes());
        organization.setManuApproveResources(organizationClass.getManuApproveResources());
        organization.setManuApproveScopes(organizationClass.getManuApproveScopes());
        organization.setGrantTypes(organizationClass.getGrantTypes());
        try {

            DBClientDetails dbClientDetails = new DBClientDetails();
            dbClientDetails.setClientSecret(UUID.randomUUID().toString());
            List<String> grantTypes = new ArrayList<>();
            if (!StringUtils.isEmpty(organizationClass.getGrantTypes())) {
                grantTypes = Arrays.asList(organization.getGrantTypes().split("\\|"));
            }

            logger.info("==================================组织模板："+organizationClass);
            //组织分类必须传
            dbClientDetails.setAuthorizedGrantTypes(grantTypes);
            dbClientDetails.setGrantTypes(organizationClass.getGrantTypes());
            logger.info("==============================grant_type="+organizationClass.getGrantTypes());
            dbClientDetails.setClientId(organization.getClientId());
            dbClientDetails.setAllowUsersToJoin(organizationClass.getAllowUsersToJoin());
            dbClientDetails.setAutoResources(autoRecource);
            dbClientDetails.setAutoScopes(autoScopes);
            dbClientDetails.setManuResources(organizationClass.getManuApproveResources());
            dbClientDetails.setManuScopes(organizationClass.getManuApproveScopes());

            logger.info("======================================organization:" + organization);
            //插入组织信息
            count = organizationService.insertOrganization(organization);
            logger.info("======================================organizationCount:" + count);


            logger.info("======================================dbClientDetails:" + dbClientDetails);
            //插入客服端授权信息
            int dbCount = dbClientDetailsService.insertClientDetails(dbClientDetails);
            logger.info("======================================插入客户端响应:" + dbCount);


            //插入组织部门（默认是顶级部门）
            OrganizationDept organizationDept = new OrganizationDept();
            organizationDept.setClientId(organization.getClientId());
            organizationDept.setDeptId(0 + "");//顶级部门
            organizationDept.setDeptParentId(-1 + "");
            organizationDept.setDeptName(organizationClass.getOrgClassName());
            organizationDept.setDeptPlace(organization.getAddressCode());
            organizationDept.setDeptPlaceDetail(organization.getAddressDetail());
            organizationDept.deptResources(organization.getAutoApproveResources());
            organizationDept.setDeptScopes(organization.getAutoApproveScopes());

            count += organizationService.insertOrganizationDept(organizationDept);
            logger.info("======================================插入组织部门响应:" + count);

        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new Exception(e.getMessage());
        }


        logger.info("======================================UserOrg:" + regUser.getClientOrgClass());
        logger.info("======================================clientId:" + organization.getClientId());


        /**2.注册法人*/
        error=new Error();
        if(regUser!=null)
        {

            List<String> clientList = new ArrayList<>();
            clientList.add(organization.getClientId());
            regUser.setApplyClientId(clientList);
            regUser.setDefaultClientId(organization.getClientId());
            logger.info("======================================regUser:" + regUser);
            if (StringUtils.isEmpty(regUser.getUserName()) || "string".equals(regUser.getUserName())) {
                regUser.setUserName(null);
            }



                    //存在ClientId,用户想加入该组织
                try {
                    for (String clientId : regUser.getApplyClientId()) {
                        DBClientDetails clientDetails = null;
                        OrganizationDept organizationDept = null;
                        clientDetails = dbClientDetailsService.getClientDetailsByClientId(clientId);
                        logger.info("clientDetails="+clientDetails);
                        if (clientDetails == null) {
                            continue; //当前clientId 无效,继续循环下一个
                        }
                        //加入 指定的部门
                        if (!StringUtils.isEmpty(regUser.getApplyDeptId())) {
                            organizationDept = userAuthorityService.getOrganizationDept(clientId, regUser.getApplyDeptId());
                        }
                        //部门不存在,则加入默认部门deptId="0"
                        if (organizationDept == null) {
                            organizationDept = userAuthorityService.getOrganizationDept(clientId, "0");
                            if (organizationDept == null) {
                                continue; //默认部门deptId="0" 无效,继续循环下一个
                            }
                        }
                        //clientId 和 deptId正常,且未创建用户
                        if (isCreatUser <= 0) {
                            //只执行一次,创建用户
                            try {
                                isCreatUser = userAuthorityService.insertOauthUser(regUser);
                                count += isCreatUser;
                            } catch (Exception e) {
                                throw new Exception(e.getMessage());
                            }
                        }
                        //logger.warn("clientDetails:"+clientDetails);
                        if (clientDetails.getAllowUsersToJoin() == null || !clientDetails.getAllowUsersToJoin()) {
                            //需要审核才能成为client域下的用户,则把申请记录到表里
                            // count += userAuthorityService.ins(regUser.getUserId(), clientId, organizationDept.getDeptId());
                            UserApplyClientResource userApplyClientResource = new UserApplyClientResource();
                            userApplyClientResource.setClientId(clientId);
                            userApplyClientResource.setResourceId(organizationClass.getManuApproveResources());
                            userApplyClientResource.setScope(organizationClass.getManuApproveScopes());
                            userApplyClientResource.setUserId(regUser.getUserId());
                            userApplyClientResource.setJob("org_corp");
                            logger.info("userApplyClientResource="+userApplyClientResource);
                            count += organizationService.insertUserApplyClientResource(userApplyClientResource);
                        } else {
                            //根据clientId给用户配置自动资源
                            LinkedHashSet<String> resourcesSet = new LinkedHashSet();
                            //String resources = "default_resources";
                            if (!StringUtils.isEmpty(clientDetails.getAutoResources())) {
                                resourcesSet.addAll(Arrays.asList(clientDetails.getAutoResources().split("\\|")));
                                //resources = clientDetails.getAutoResources();
                            }
                            //参考 部门,添加部门资源
                            if (!StringUtils.isEmpty(organizationDept.getDeptResources())) {
                                resourcesSet.addAll(Arrays.asList(organizationDept.getDeptResources().split("\\|")));
                                //resources = clientDetails.getAutoResources();
                            }
                            if (resourcesSet.size() == 0) {
                                resourcesSet.add("default_resources");
                            }

                            //根据clientId给用户配置自动权限
                            LinkedHashSet<String> scopesSet = new LinkedHashSet();
                            //String scopes = "default_scopes";
                            if (!StringUtils.isEmpty(clientDetails.getAutoScopes())) {
                                scopesSet.addAll(Arrays.asList(clientDetails.getAutoScopes().split("\\|")));
                                //scopes = clientDetails.getAutoScopes();
                            }
                            //参考 部门,添加部门权限
                            if (!StringUtils.isEmpty(organizationDept.getDeptScopes())) {
                                scopesSet.addAll(Arrays.asList(organizationDept.getDeptScopes().split("\\|")));
                                //resources = clientDetails.getAutoResources();
                            }
                            if (scopesSet.size() == 0) {
                                scopesSet.add("default_scopes");
                            }

                            //查询applyOpenid是否存在,不存在则可使用该applyOpenid
                            String openid = UUID.randomUUID().toString();
                            regUser.setApplyOpenid(openid);//记录OpenId
                            if (!StringUtils.isEmpty(regUser.getApplyOpenid()) && userAuthorityService.getOpenIdCount(clientId, regUser.getApplyOpenid()) <= 0) {
                                openid = regUser.getApplyOpenid();
                            }
                            //用户插入组织(client域)
                            //数据库，需保证resources,scopes  NOT NULL（已加约束），所以此处resources,scopes不能为null
                            //logger.warn("clientId:"+clientId+",UserId:"+regUser.getUserId()+",openid:"+openid+",resources:"+resources+",scopes:"+scopes);
                            count += userAuthorityService.insertOpenid(clientId, regUser.getUserId(), openid, String.join("|", resourcesSet), String.join("|", scopesSet));
                            //插入员工信息  员工必须有job字段标识  否则无权限
                            OrganizationEmp organizationEmp = new OrganizationEmp();
                            organizationEmp.setClientId(clientId);
                            organizationEmp.setDeptId(organizationDept.getDeptId());
                            organizationEmp.setUserId(regUser.getUserId());
                            organizationEmp.setJob("org_corp");
                            count += userAuthorityService.insertOrganizationEmp(organizationEmp);
                        }

                    }
                } catch (Exception e) {
                    logger.info(e.getMessage());
                    throw new Exception(e.getMessage());
                }


        }


        return regUser;
    }

    @Override
    public List<RegUser> batchRegisterCorp(List<RegUser> regUserList, String autoRecource, String autoScopes) throws Exception {
        logger.info("regUserList="+regUserList+",autoRecource="+autoRecource+",autoScopes"+autoScopes);
        int count=0;
        List<RegUser> regUsers=new ArrayList<>();
        try {
            for(RegUser regUser:regUserList){
                logger.info("regUser="+regUser);
                regUser=  registerCorp(regUser,autoRecource,autoScopes);
                logger.info("regUser1="+regUser);
                regUsers.add(regUser);
            }
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new Exception(e.getMessage());
        }
        return regUsers;
    }

    @Override
    public int applyAddOrg(String orgId, String openId,String job) throws Exception {

        int count=0;
        DBClientDetails clientDetails = null;
        OrganizationDept organizationDept = new OrganizationDept();
        organizationDept = userAuthorityService.getOrganizationDept(orgId, "0");

        clientDetails = dbClientDetailsService.getClientDetailsByClientId(orgId);
        logger.info("clientDetails="+clientDetails);
        //根据clientId给用户配置自动资源
        LinkedHashSet<String> resourcesSet = new LinkedHashSet();
        //String resources = "default_resources";
        if (!StringUtils.isEmpty(clientDetails.getManuResources())) {
            resourcesSet.addAll(Arrays.asList(clientDetails.getManuResources().split("\\|")));
            //resources = clientDetails.getAutoResources();
        }
        //参考 部门,添加部门资源
        if (!StringUtils.isEmpty(organizationDept.getDeptResources())) {
            resourcesSet.addAll(Arrays.asList(organizationDept.getDeptResources().split("\\|")));
            //resources = clientDetails.getAutoResources();
        }
        if (resourcesSet.size() == 0) {
            resourcesSet.add("default_resources");
        }

        //根据clientId给用户配置自动权限
        LinkedHashSet<String> scopesSet = new LinkedHashSet();
        //String scopes = "default_scopes";
        if (!StringUtils.isEmpty(clientDetails.getManuScopes())) {
            scopesSet.addAll(Arrays.asList(clientDetails.getManuScopes().split("\\|")));
            //scopes = clientDetails.getAutoScopes();
        }
        //参考 部门,添加部门权限
        if (!StringUtils.isEmpty(organizationDept.getDeptScopes())) {
            scopesSet.addAll(Arrays.asList(organizationDept.getDeptScopes().split("\\|")));
            //resources = clientDetails.getAutoResources();
        }
        if (scopesSet.size() == 0) {
            scopesSet.add("default_scopes");
        }

        String userId= userAuthorityService.queryUserIdByUserIdAndClientId(openId);

        //插入申请记录
        UserApplyClientResource userApplyClientResource = new UserApplyClientResource();
        userApplyClientResource.setClientId(orgId);
        userApplyClientResource.setResourceId(String.join("|", resourcesSet));
        userApplyClientResource.setScope(String.join("|", scopesSet));
        userApplyClientResource.setUserId(userId);
        userApplyClientResource.setJob(job);
        count += organizationService.insertUserApplyClientResource(userApplyClientResource);
        return count;
    }
}
